package com.wuyb.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wuyb.mapper.*;
import com.wuyb.pojo.*;
import com.wuyb.pojo.entity.BaseResponse;
import com.wuyb.pojo.entity.ResultUtils;
import com.wuyb.pojo.param.MeetingAddParam;
import com.wuyb.pojo.param.MeetingLicenceParam;
import com.wuyb.pojo.param.MeetingUpdateParam;
import com.wuyb.pojo.param.PageParam;
import com.wuyb.service.MeetingPasswordService;
import com.wuyb.service.MeetingService;
import com.wuyb.socket.SocketSender;
import com.wuyb.util.MeetingParamConverter;
import com.wuyb.util.MyUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

/**
 * 会议服务实现类
 *
 * @Author: wyb
 * @Date: 2024/01/05/14:16
 * @Description:
 */
@Service
@Slf4j
public class MeetingServiceImpl extends ServiceImpl<MeetingMapper, Meeting> implements MeetingService {

    @Resource
    private MeetingMapper meetingMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private MeetingUserMapper meetingUserMapper;

    @Resource
    private SocketSender socketSender;

    @Resource
    private MeetingApplicationMapper meetingApplicationMapper;

    @Resource
    private MeetingNoticeMapper meetingNoticeMapper;

    @Resource
    private MeetingNoticeUserMapper meetingNoticeUserMapper;

    @Resource
    private MeetingPasswordService meetingPasswordService;


    /**
     * 查询会议
     *
     * @param pageParam
     * @return
     */
    @Override
    public BaseResponse<?> select(PageParam pageParam) {
        return select(pageParam, null);
    }

    @Override
    public BaseResponse<?> select(PageParam pageParam, QueryWrapper<Meeting> wrapper) {
        IPage<Meeting> list = listPage(pageParam, wrapper);
        return ResultUtils.success(list);
    }

    @Override
    public BaseResponse<?> add(MeetingAddParam meeting) {
        try {
            Meeting meetingAdd = meetingAdd(meeting);
            addMeetingNotice(
                    new MeetingNotice()
                            .setMeetingId(meetingAdd.getId())
                            .setTitle(String.format("欢迎来参加 %s 会议", meeting.getName()))
                            .setContent(String.format("我们会议将于 %s 开始", meeting.getStartDate().toString().replaceAll("T", " ")))
                            .setType(2)
            );
        } catch (Exception e) {
            log.error(e.getMessage());
            return ResultUtils.error(e.getMessage());
        }

        return ResultUtils.success(meeting, "添加成功");
    }

    @Override
    public BaseResponse<?> update(MeetingUpdateParam meeting) {
        if (meetingUpdateById(meeting) > 0) {
            return ResultUtils.success(meeting, "修改成功");
        } else {
            return ResultUtils.error("修改失败");
        }
    }

    @Override
    public BaseResponse<?> delete(String mid) {
        Meeting meeting = meetingDeleteById(mid);
        if (meeting != null) {
            return ResultUtils.success(meeting, "结束成功");
        } else {
            return ResultUtils.error("结束失败");
        }
    }

    /**
     * 输出当前用户创建的会议
     *
     * @param pageParam
     * @return
     */
    @Override
    public BaseResponse<?> selectByUser(PageParam pageParam) {
        User user = MyUtil.getUser();
        if (user == null) {
            return ResultUtils.error("获取用户信息失败，请重新登录");
        }
        return select(pageParam, new QueryWrapper<Meeting>().eq("user_id_xq", user.getId()));
    }

    @Override
    public BaseResponse<?> addByUser(MeetingAddParam meeting) {
        return add(meeting);
    }

    @Override
    public BaseResponse<?> updateByUser(MeetingUpdateParam meeting) {
        if (!isBelongUser(meeting.getId())) {
            return ResultUtils.error("修改失败");
        }

        return update(meeting);
    }

    @Override
    public BaseResponse<?> deleteByUser(String mid) {
        if (!isBelongUser(mid)) {
            return ResultUtils.error("结束失败");
        }
        return delete(mid);
    }

    @Override
    public BaseResponse<?> setLicence(MeetingLicenceParam param) {
        int result = meetingMapper.updateById(
                new Meeting()
                        .setId(param.getId())
                        .setHaveLicence(param.getHaveLicence())
        );
        if (param.getHaveLicence()) {
            meetingPasswordService.update(
                    new UpdateWrapper<MeetingPassword>()
                            .eq("meeting_id_xq", param.getId())
                            .set("enabled_xq", false)
            );
        }
        if (result != 0) {
            return ResultUtils.success("修改成功");
        }
        return ResultUtils.error("修改失败");
    }

    @Override
    public BaseResponse<?> setLicenceByUser(MeetingLicenceParam param) {
        if (!isBelongUser(param.getId())) {
            return ResultUtils.error("修改失败");
        }
        return setLicence(param);
    }

    /**
     * 分页查看自己的历史会议列表
     *
     * @return
     */
    @Override
    public BaseResponse<?> selectByHistory() {
        User user = MyUtil.getUser();
        IPage<Meeting> meetingIPage = meetingMapper.selectMeetingByCreater(
                new Page<>(0, -1),
                new QueryWrapper<Meeting>()
                        .eq("user_id_xq", user.getId())
                        .eq("to_owner_hidden_xq", 0)
                        .eq("end_xq", 1)
        );

        IPage<Meeting> joinedMeetings = meetingMapper.selectMeetingByParticipantsEnd(new Page<>(0, -1), user.getId());

        List<Meeting> records = meetingIPage.getRecords();
        records.addAll(joinedMeetings.getRecords());
        records.sort(new Comparator<Meeting>() {
            @Override
            public int compare(Meeting o1, Meeting o2) {
                return o2.getEndDate().compareTo(o1.getEndDate());
            }
        });

        meetingIPage.setRecords(records);
        return ResultUtils.success(meetingIPage);
    }


    /**
     * 分页查看自己已经加入的会议
     *
     * @param pageParam
     * @return
     */
    @Override
    public BaseResponse<?> selectByUserJoined(PageParam pageParam) {
        User user = MyUtil.getUser();
        if (user == null) {
            return ResultUtils.error("获取用户信息失败，请重新登录");
        }
        Page<Meeting> page = new Page<>(pageParam.getCurrent(), pageParam.getSize());
        IPage<Meeting> meetingIPage = meetingMapper.selectMeetingByParticipants(page, user.getId(), null);
        return ResultUtils.success(meetingIPage);
    }


    @Override
    public BaseResponse<?> joinMeeting(String mid, String password) {
        return isjoinMeeting(mid, false, password);
    }

    @Override
    public BaseResponse<?> outMeeting(String mid) {
        return isjoinMeeting(mid, true, null);
    }

    @Override
    public BaseResponse<?> getMeetingById(String id, Boolean isAdmin) {
        User user = MyUtil.getUser();
        assert user != null;
        Meeting existMeetByUser = meetingMapper.getExistMeetByUser(id, user.getId());

        if (existMeetByUser == null) {
            existMeetByUser = meetingMapper.selectById(id);
            if (existMeetByUser != null && (isAdmin || existMeetByUser.getUserId().equals(user.getId()))) {
                return ResultUtils.success(existMeetByUser);
            }
            return ResultUtils.error("找不到该会议，请检查会议号");
        }
        return ResultUtils.success(existMeetByUser);
    }

    @Override
    public BaseResponse<?> selectHadSignInList(String mid, Integer current, Integer size) {
        IPage<User> userList = meetingUserMapper.selectHadSignInList(new Page<>(current, size), mid);
        return ResultUtils.success(userList);
    }

    @Override
    public BaseResponse<?> selectMeetingApplications(Integer current, Integer size) {
        Integer userId = MyUtil.getUser().getId();
        IPage<MeetingApplication> meetingApplicationIPage = meetingApplicationMapper.selectMeetingApplication(userId, new Page<>(current, size));
        return ResultUtils.success(meetingApplicationIPage);
    }

    @Override
    public BaseResponse<?> replyMeetingApplication(String meetingid, Integer userid, Integer result) {
        int update = meetingApplicationMapper.update(
                new MeetingApplication().setState(1),
                new QueryWrapper<MeetingApplication>()
                        .eq("meeting_id_xq", meetingid)
                        .eq("application_id_xq", userid)
                        .eq("state_xq", 0)
        );
        if (update == 0) {
            return ResultUtils.error("会议查找错误，请检查相关参数");
        }
        if (result == 1) {
            joinMeeting(meetingid, userid);
            insertMeetingNoticePushToUser(meetingid, userid);
            IPage<MeetingNotice> meetingNoticeIPage = meetingNoticeMapper.selectMeetingNoticePushByUid(userid, new Page<>(0, -1));
            JSONObject jsonObject = JSONObject.from(meetingNoticeIPage);
            socketSender.sendInform(jsonObject, 3, userid);
            return ResultUtils.success("同意成功");
        }
        return ResultUtils.success("忽略成功");
    }

    @Override
    public BaseResponse<?> selectMeetingNoticePush(Integer current, Integer size) {
        Integer userId = MyUtil.getUser().getId();
        IPage<MeetingNotice> meetingNoticeIPage = meetingNoticeMapper.selectMeetingNoticePushByUid(userId, new Page<>(current, size));
        return ResultUtils.success(meetingNoticeIPage);
    }

    @Override
    public BaseResponse<?> readMeetinInfrom(Integer informId) {
        int update = meetingNoticeUserMapper.updateById(
                new MeetingNoticeUser()
                        .setId(informId)
                        .setState(1)
        );
        return ResultUtils.success("");
    }

    @Override
    public BaseResponse<?> addMeetingNotice(MeetingNotice meetingNotice) {
        if (!isBelongUser(meetingNotice.getMeetingId())) {
            return ResultUtils.error("添加失败，没有权限");
        }
        meetingNotice.setSenderId(MyUtil.getUser().getId());
        meetingNotice.setSendTime(LocalDateTime.now());
        meetingNotice.setUpdateTime(LocalDateTime.now());
        int insert = meetingNoticeMapper.insert(meetingNotice);
        if (meetingNotice.getType() == 2) {
            sendMeetNoticeToAllUser(meetingNotice);
        }
        return insert > 0 ? ResultUtils.success("添加公告成功") : ResultUtils.error("添加公告失败");
    }

    @Override
    public BaseResponse<?> getMeetingNoticeById(String mid, Integer current, Integer size) {
        IPage<MeetingNotice> noticeIPage = meetingNoticeMapper.selectMeetingNotice(mid, new Page<>(current, size));
        return ResultUtils.success(noticeIPage);
    }

    @Override
    public BaseResponse<?> delMeetingNoticeById(String meeingId, Integer noticeId) {
        if (!isBelongUser(meeingId)) {
            return ResultUtils.error("删除失败，没有权限");
        }
        int result = meetingNoticeMapper.deleteById(noticeId);
        return result > 0 ? ResultUtils.success("删除成功") : ResultUtils.error("删除失败");
    }

    @Override
    public BaseResponse<?> updateMeetingNotice(MeetingNotice meetingNotice) {
        if (!isBelongUser(meetingNotice.getMeetingId())) {
            return ResultUtils.error("编辑失败，没有权限");
        }
        meetingNotice.setSenderId(MyUtil.getUser().getId());
        meetingNotice.setUpdateTime(LocalDateTime.now());
        // 将之前的通知变为已读
        meetingNoticeUserMapper.update(
                new MeetingNoticeUser().setState(1),
                new QueryWrapper<MeetingNoticeUser>()
                        .eq("notice_id_xq", meetingNotice.getId())
        );
        int result = meetingNoticeMapper.updateById(meetingNotice);
        if (meetingNotice.getType() == 2) {
            sendMeetNoticeToAllUser(meetingNotice);
        }
        return result > 0 ? ResultUtils.success("编辑成功") : ResultUtils.error("编辑失败");
    }

    @Override
    public BaseResponse<?> getMeetingUsersList(String mid, Integer current, Integer size) {
        IPage<MeetingUser> meetingUserIPage = meetingUserMapper.selectMeetingUsersList(new Page<>(current, size), mid);
        return ResultUtils.success(meetingUserIPage);
    }

    @Override
    public BaseResponse<?> delMeetingUserById(String mid, Integer userId) {
        if (!isBelongUser(mid)) {
            return ResultUtils.error("踢出失败，没有权限");
        }
        meetingUserMapper.delete(
                new QueryWrapper<MeetingUser>()
                        .eq("users_id_xq", userId)
                        .eq("meeting_id_xq", mid)
        );
        Meeting meeting = meetingMapper.selectById(mid);

        sendHiddenMeetNoticeToOneUser(mid, userId,
                String.format("你已被踢出 %s 会议", meeting.getName()),
                String.format("你已被踢出 %s 会议<br>会议号：%s", meeting.getName(), meeting.getId())
        );
        socketSender.sendActionToMeetUser("refresh", mid, userId, "你已被提出会议", false);
        return ResultUtils.success("成功提出会议");
    }

    @Override
    public BaseResponse<?> getExistUserList(String mid) {
        return ResultUtils.success(socketSender.getUserListByMeetId(mid));
    }

    @Override
    public BaseResponse<?> delHistoryMeeting(String mid) {
        Integer userId = MyUtil.getUser().getId();
        Meeting meeting = meetingMapper.selectById(mid);
        Integer i = null;
        if (meeting.getUserId().equals(userId)) {
            i = meetingMapper.delHistoryMeting(mid, userId);
        } else {
            i = meetingUserMapper.delHistoryMeeting(mid, userId);
        }
        if (i != null && i > 0) {
            return ResultUtils.success("记录成功删除");
        }
        return ResultUtils.error("记录删除失败");
    }

    @Override
    public BaseResponse<?> getMeetingUsersStateById(String mid, Integer uid) {
        MeetingUser meetingUser = meetingUserMapper.selectOne(
                new QueryWrapper<MeetingUser>()
                        .eq("meeting_id_xq", mid)
                        .eq("users_id_xq", uid)
        );
        return ResultUtils.success(meetingUser);
    }

    @Override
    public BaseResponse<?> setMeetingUsersStateByIdMany(String mid, JSONObject jsonObject) {
        if (!isBelongUser(mid)) {
            return ResultUtils.error("修改失败，你没有权限");
        }
        List<Map<String, Object>> list = (List<Map<String, Object>>) jsonObject.get("userId");

        for (Map<String, Object> map : list) {
            QueryWrapper<MeetingUser> wrapper = new QueryWrapper<MeetingUser>()
                    .eq("meeting_id_xq", mid)
                    .eq("users_id_xq", map.get("userId"));

            // 修改前
            MeetingUser meetingUser = meetingUserMapper.selectOne(wrapper);
            // 修改后
            MeetingUser meetingUsers = MeetingUser.builder()
                    .hadMuted((Boolean) map.get("hadMuted"))
                    .hadBanup((Boolean) map.get("hadBanup"))
                    .build();

            if (!meetingUsers.getHadMuted().equals(meetingUser.getHadMuted())) {
                if (meetingUsers.getHadMuted()) {
                    socketSender.sendActionToMeetUser("stop_speech", mid, (Integer) map.get("userId"), "你已被禁止开麦", false);
                } else {
                    socketSender.sendActionToMeetUser("open_speech", mid, (Integer) map.get("userId"), "success:你已被允许开麦", false);
                }
            }

            if (!meetingUsers.getHadBanup().equals(meetingUser.getHadBanup())) {
                if (meetingUsers.getHadBanup()) {
                    socketSender.sendActionToMeetUser("stop_up", mid, (Integer) map.get("userId"), "你已被禁止投屏", false);
                } else {
                    socketSender.sendActionToMeetUser("open_up", mid, (Integer) map.get("userId"), "success:你已被允许投屏", false);
                }
            }
            meetingUserMapper.update(meetingUsers, wrapper);
        }
        return ResultUtils.success("修改成功");
    }

    @Override
    public BaseResponse<?> setMeetingUsersStateByIdOne(String mid, Integer uid, JSONObject jsonObject) {
        Boolean uping = jsonObject.getBoolean("uping");
        Boolean speeching = jsonObject.getBoolean("speeching");

        QueryWrapper<MeetingUser> wrapper = new QueryWrapper<MeetingUser>()
                .eq("meeting_id_xq", mid)
                .eq("users_id_xq", uid);

        if (meetingUserMapper.selectOne(wrapper) == null && meetingMapper.selectById(mid).getUserId().equals(uid)) {
            meetingUserMapper.insert(new MeetingUser().setMeetingId(mid).setUserId(uid).setIsFounder(true));
        }

        if (uping != null) {
            meetingUserMapper.update(new MeetingUser().setUping(uping), wrapper);
        } else if (speeching != null) {
            meetingUserMapper.update(new MeetingUser().setSpeeching(speeching), wrapper);
        } else {
            return ResultUtils.error("修改失败");
        }
        socketSender.sendStateToMeetUser(mid, uid, uping, speeching);
        return ResultUtils.success("");
    }

    @Override
    public BaseResponse<?> selectAllStartDateTime() {
        return ResultUtils.success(meetingMapper.selectAllStartDateTime(false));
    }

    @Override
    public BaseResponse<?> selectStartDateTime() {
        return ResultUtils.success(meetingMapper.selectAllStartDateTime(true));
    }

    @Override
    public BaseResponse<?> getMeetingPasswordById(String mid) {
        if (!isBelongUser(mid)) {
            return ResultUtils.error("没有权限");
        }
        return getMeetingPasswordOne(mid);
    }

    @Override
    public BaseResponse<?> getMeetingPasswordByIdAdmin(String mid) {
        return getMeetingPasswordOne(mid);
    }


    /**
     * 查询所有会议数据
     *
     * @param pageParam
     * @param wrapper
     * @return
     */
    private IPage<Meeting> listPage(PageParam pageParam, QueryWrapper<Meeting> wrapper) {
        Page<Meeting> page = new Page<>(pageParam.getCurrent(), pageParam.getSize());
        return meetingMapper.selectMeetingByCreater(page, wrapper);
    }

    private IPage<Meeting> listPage(PageParam pageParam) {
        return listPage(pageParam, null);
    }


    /**
     * 会议添加
     *
     * @param meetingAddParam
     * @return
     */
    private Meeting meetingAdd(MeetingAddParam meetingAddParam) {
        Meeting meeting = MeetingParamConverter.getMeeting(meetingAddParam);
        // 获取登录人的Id
        User principal = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        meeting.setUserId(principal.getId());
        // 获取现在的时间
        meeting.setCreateDate(LocalDateTime.now());
        meetingMapper.insert(meeting);
        // 添加密码
        meetingPasswordService.insert(meeting.getId(), meetingAddParam.getPassword(), meetingAddParam.getPassEnabled());
        return meeting;
    }


    /**
     * 修改会议
     *
     * @param meetingUpdateParam
     * @return
     */
    private int meetingUpdateById(MeetingUpdateParam meetingUpdateParam) {
        boolean update = meetingPasswordService.update(
                new QueryWrapper<MeetingPassword>()
                        .eq("meeting_id_xq", meetingUpdateParam.getId())
                        .eq("password_xq", meetingUpdateParam.getPassword())
                        .eq("enabled_xq", meetingUpdateParam.getPassEnabled())
        );
        if (!update) {
            meetingPasswordService.insert(meetingUpdateParam.getId(), meetingUpdateParam.getPassword(), meetingUpdateParam.getPassEnabled());
        }
        return meetingMapper.updateById(MeetingParamConverter.getMeeting(meetingUpdateParam));
    }


    /**
     * 删除会议
     *
     * @param id
     * @return
     */
    private Meeting meetingDeleteById(String id) {
        Meeting meeting = meetingMapper.selectById(id);
        if (meeting != null && meetingMapper.deleteById(id) > 0) {
            sendHiddenMeetMeetNoticeToAllUser(meeting.getId(),
                    String.format("%s 会议已经结束", meeting.getName()),
                    String.format("%s 会议已经结束", meeting.getName())
            );
            // 写入结束时间
            meetingMapper.updateEndDate(id, LocalDateTime.now().toString());
            // 向房间内其他人发送刷新行为
            socketSender.sendActionToMeetUser("refresh", id, meeting.getUserId(), null, true);
            return meeting;
        }
        return null;
    }


    /**
     * 发送隐藏会议公告通知给所有参会用户，该公告只能通过通知列表才能看见
     *
     * @param meetId
     * @param title
     * @param content
     */
    private void sendHiddenMeetMeetNoticeToAllUser(String meetId, String title, String content) {
        // 创建除消息实体，添加到数据库
        MeetingNotice meetingNotice = MeetingNotice.builder()
                .meetingId(meetId)
                .title(title)
                .content(content)
                .senderId(MyUtil.getUser().getId())
                .sendTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .hidden(true)
                .build();

        meetingNoticeMapper.insert(meetingNotice);
        sendMeetNoticeToAllUser(meetingNotice);
    }


    /**
     * 发送会议通知给所有用户
     *
     * @param meetingNotice
     */
    private void sendMeetNoticeToAllUser(MeetingNotice meetingNotice) {
        List<User> userList = selectMeetWithParticipantById(meetingNotice.getMeetingId());
        // 加入到数据库
        List<Integer> informs = insertMeetingNoticePushToUserList(meetingNotice.getId(), userList);

        // 加入会议与创建会议的用户对象，
        Meeting meeting = meetingMapper.selectMeetingByCreaterOne(meetingNotice.getMeetingId());
        User user = userMapper.selectById(meetingNotice.getSenderId());
        meetingNotice.setMeeting(meeting);
        meetingNotice.setSender(user);

        sendMeetNoticeToAllUsers(meetingNotice, userList, informs);
    }


    /**
     * 查询出所有参加该会议的用户列表
     *
     * @param meetingId
     * @return
     */
    private List<User> selectMeetWithParticipantById(String meetingId) {
        return meetingMapper.selectOneByParticipantId(meetingId);
    }


    /**
     * 将该公告推送给该会议下的所有成员，并返回刚刚新增数据的Id，（informId）
     * <p>
     * 将通知ID和用户建立起对应关系
     *
     * @param noticeId
     * @param userList
     * @return
     */
    private List<Integer> insertMeetingNoticePushToUserList(Integer noticeId, List<User> userList) {
        // 如果该公告已经存在，就把该公告已读的删除
        meetingNoticeUserMapper.delete(
                new QueryWrapper<MeetingNoticeUser>()
                        .eq("notice_id_xq", noticeId)
                        .eq("state_xq", 1)
        );
        List<Integer> informIds = new ArrayList<>();

        for (User u : userList) {
            MeetingNoticeUser meetingNoticeUser = MeetingNoticeUser.builder()
                    .noticeId(noticeId)
                    .userId(u.getId())
                    .state(0)
                    .build();
            meetingNoticeUserMapper.insert(meetingNoticeUser);
            informIds.add(meetingNoticeUser.getId());
        }
        return informIds;
    }


    /**
     * 将公告在线发送给该列表中的用户，informId对应数据库中他们的通知消息Id
     */
    private void sendMeetNoticeToAllUsers(MeetingNotice meetingNotice, List<User> userList, List<Integer> informs) {
        JSONObject jsonObject = JSONObject.from(meetingNotice);
        jsonObject.put("updateTime", jsonObject.getString("updateTime").replace("T", " "));
        for (int i = 0; i < userList.size(); i++) {
            jsonObject.put("informId", informs.get(i));
            socketSender.sendInform(jsonObject, 3, userList.get(i).getId());
            try {
                // 睡眠一下，不然回串线
                Thread.sleep(20);
            } catch (InterruptedException e) {
                log.error(e.getMessage());
            }
        }
    }


    /**
     * 查看这个会议是否属于这个用户
     *
     * @param meetingId
     * @return
     */
    private boolean isBelongUser(String meetingId) {
        QueryWrapper<Meeting> wrapper = new QueryWrapper<>();
        User user = MyUtil.getUser();
        if (user == null) {
            return false;
        }
        wrapper.eq("id_xq", meetingId);
        wrapper.eq("user_id_xq", user.getId());
        Meeting meeting = meetingMapper.selectOne(wrapper);
        return meeting != null;
    }


    /**
     * 判断是否已经加入了会议，isOut为假就是加入了会议，反之则退出了会议
     *
     * @param mid
     * @param isOut
     * @param password
     * @return
     */
    private BaseResponse<?> isjoinMeeting(String mid, Boolean isOut, String password) {
        Meeting meeting = meetingMapper.selectById(mid);
        if (meeting == null) {
            return ResultUtils.error("会议没有找到。请检查会议号");
        }
        if (meeting.getEnd()) {
            return ResultUtils.error("该会议已结束");
        }
        User user = MyUtil.getUser();
        if (user == null) {
            return ResultUtils.error("获取用户信息失败，请重新登录");
        }

        QueryWrapper<MeetingUser> wrapper = new QueryWrapper<MeetingUser>()
                .eq("users_id_xq", user.getId())
                .eq("meeting_id_xq", meeting.getId());

        // 判断是否退出了
        if (isOut) {
            int delete = meetingUserMapper.delete(wrapper);
            return delete > 0 ? ResultUtils.success("退出成功") : ResultUtils.error("退出失败");
        }

        if (meeting.getUserId().equals(user.getId()) || meetingUserMapper.selectOne(wrapper) != null) {
            return ResultUtils.error("你已经参加了这个会议");
        }
        // 判断人数是否已经最大了
        if (meetingUserMapper.selectCount(
                new QueryWrapper<MeetingUser>()
                        .eq("meeting_id_xq", mid)
                        .ne("users_id_xq", meeting.getUserId())) >= meeting.getMaxNumber() - 1) {
            return ResultUtils.error("会议人数已经达到最大限制了");
        }

        // 判断是否要申请才能入会
        if (meeting.getHaveLicence()) {
            MeetingApplication one = meetingApplicationMapper.selectOne(
                    new QueryWrapper<MeetingApplication>()
                            .eq("application_id_xq", user.getId())
                            .eq("meeting_id_xq", meeting)
                            .eq("state_xq", 0)
            );
            if (one != null) {
                return ResultUtils.error("申请失败，你已经申请过该会议了");
            }

            MeetingApplication application = MeetingApplication.builder()
                    .applicationId(user.getId())
                    .meetingId(meeting.getId())
                    .state(0)
                    .sendTime(LocalDateTime.now())
                    .build();

            meetingApplicationMapper.insert(application);

            application.setMeeting(meeting);
            application.setUsers(user);
            JSONObject jsonObject = JSONObject.from(application);
            socketSender.sendInform(jsonObject, 2, meeting.getUserId());
            return ResultUtils.success("成功申请加入会议，请等待会议发起人的同意");
        } else {
            MeetingPassword meetingPasswordOne = meetingPasswordService.getMeetingPasswordOne(mid);
            if (meetingPasswordOne != null && meetingPasswordOne.getEnabled()) {
                if (!meetingPasswordOne.getPassword().equals(password)) {
                    return ResultUtils.error("会议密码错误");
                }
            }
        }

        joinMeeting(meeting.getId(), user.getId());
        insertMeetingNoticePushToUser(meeting.getId(), user.getId());
        return ResultUtils.success("参加成功");
    }

    /**
     * 加入会议
     *
     * @param meetingId
     * @param userId
     */
    private void joinMeeting(String meetingId, Integer userId) {
        meetingUserMapper.insert(new MeetingUser().setMeetingId(meetingId).setUserId(userId));
    }


    /**
     * 对方刚加入会议的时候，将之前的推送公告加入到该用户的通知当中
     *
     * @param meetingId
     * @param userId
     */
    private void insertMeetingNoticePushToUser(String meetingId, Integer userId) {
        meetingNoticeUserMapper.insertMeetingNoticePushToUser(meetingId, userId);
    }


    /**
     * 发送隐藏会议公告通知给指定用户，该公关稿只能通过通知列表才能看到
     *
     * @param meetId
     * @param userId
     * @param title
     * @param content
     */
    private void sendHiddenMeetNoticeToOneUser(String meetId, Integer userId, String title, String content) {
        Meeting meeting = meetingMapper.selectById(meetId);
        User user = userMapper.selectById(userId);

        MeetingNotice meetingNotice = MeetingNotice.builder()
                .meetingId(meetId)
                .meeting(meeting)
                .title(title)
                .content(content)
                .senderId(MyUtil.getUser().getId())
                .sender(MyUtil.getUser())
                .sendTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .hidden(true)
                .build();

        meetingNoticeMapper.insert(meetingNotice);
        List<User> list = new ArrayList<>();
        list.add(user);

        List<Integer> informIds = insertMeetingNoticePushToUserList(meetingNotice.getId(), list);
        JSONObject jsonObject = JSONObject.from(meetingNotice);
        jsonObject.put("updateTime", jsonObject.getString("updateTime").replace("T", " "));
        jsonObject.put("informId", informIds.get(0));
        socketSender.sendInform(jsonObject, 3, userId);
    }


    /**
     * 获取会议密码
     * @param meetingId
     * @return
     */
    private BaseResponse<?> getMeetingPasswordOne(String meetingId) {
        return ResultUtils.success(meetingPasswordService.getMeetingPasswordOne(meetingId));
    }
}
